using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;

namespace HZY.Admin.Core
{
    using HZY.Admin.Services.Sys;
    using HZY.Toolkits;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;

    public class HZYAppMiddleware : IMiddleware
    {
        protected string body { get; set; }

        protected readonly AccountService service;
        protected readonly Stopwatch sw;

        public HZYAppMiddleware(AccountService _service)
        {
            this.service = _service;
            if (this.sw == null)
            {
                this.sw = new Stopwatch();
            }
        }

        public async Task InvokeAsync(HttpContext context, RequestDelegate next)
        {
            //记录 api 执行耗时
            sw.Restart();

            if (this.IsApi(context))
            {
                //启用倒带功能，就可以让 Request.Body 可以再次读取
                context.Request.EnableBuffering();
                //读取 body 信息
                var reader = new StreamReader(context.Request.Body);
                body = await reader.ReadToEndAsync();
                context.Request.Body.Position = 0;//必须存在
            }

            await next.Invoke(context);

            sw.Stop();

            if (this.IsApi(context))
            {
                await service.InsertAppLogAsync(body, sw.ElapsedMilliseconds);
            }

            Tools.Log.Write($"请求：{context.Request.Path} 耗时：{sw.ElapsedMilliseconds} 毫秒!");

        }

        /// <summary>
        /// 判断请求类型 是否 是 api
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        private bool IsApi(HttpContext context)
        {
            var contentTypes = new string[] { "application/json", "text/html" };

            var flag = false;

            foreach (var item in contentTypes)
            {
                if (context.Response.ContentType == null) continue;

                flag = context.Response.ContentType.StartsWith(item);

                if (flag) break;

            }

            return flag;
        }


    }
}